/**
 * 
 */
package fr.gfi.agraf.service.impl;

import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import fr.gfi.agraf.exception.AgrafException;
import fr.gfi.agraf.persistence.dao.IEtatDAO;
import fr.gfi.agraf.persistence.dao.IPerimetreDAO;
import fr.gfi.agraf.persistence.dao.IPoiPerimetreDAO;
import fr.gfi.agraf.persistence.dao.IUtilisateurDAO;
import fr.gfi.agraf.persistence.entity.Perimetre;
import fr.gfi.agraf.persistence.entity.Utilisateur;
import fr.gfi.agraf.service.INotificationService;
import fr.gfi.agraf.service.IPerimetreService;
import fr.gfi.agraf.service.mapper.PerimetreMapper;
import fr.gfi.agraf.service.mapper.UtilisateurMapper;
import fr.gfi.agraf.utils.PropertiesUtils;
import fr.gfi.agraf.vue.bean.PerimetreDTO;

/**
 * @author eleve
 * 
 */
@Service("PerimetreService")
@Transactional(propagation = Propagation.REQUIRED)
public class PerimetreService implements IPerimetreService {

	private static final String ERREUR_PERIMETRE_NOTFOUND = "erreur.perimetre.notfound";

	private static final String UTILISATEUR_TACHE_AUCUNE = "utilisateur.tache.aucune";

	private static final String ERREUR_PERIMETRE_NON_VIDE = "erreur.perimetre.impossible.supprimer";

	private static final String MESSAGE_NOTIF_PERIMETRE_CREE = "notification.ajout.perimetre";

	private static final String MESSAGE_NOTIF_PERIMETRE_SUPPR = "notification.suppr.perimetre";

	private static final Long ID_PROFIL_ADMINISTRATEUR = 1L;

	@Autowired
	private IPerimetreDAO perimetreDAO;

	@Autowired
	private IPoiPerimetreDAO poiPerimetreDAO;

	@Autowired
	private IEtatDAO etatDAO;

	@Autowired
	private INotificationService notificationService;

	@Autowired
	private IUtilisateurDAO utilisateurDAO;

	/*
	 * (non-Javadoc)
	 * 
	 * @see fr.gfi.agraf.service.IPerimetreService#getListePerimetre()
	 */
	public List<PerimetreDTO> getListePerimetre() throws AgrafException {
		final List<PerimetreDTO> listeOutput = PerimetreMapper.entityToDTOList(perimetreDAO.listerTous());
		if (CollectionUtils.isEmpty(listeOutput)) {
			throw new AgrafException(ERREUR_PERIMETRE_NOTFOUND);
		}
		return listeOutput;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * fr.gfi.agraf.service.IPerimetreService#ajouterPerimetre(fr.gfi.agraf.
	 * vue.bean.PerimetreDTO)
	 */
	public void ajouterPerimetre(final PerimetreDTO perimetreDTO, final Long idUserCreateur) {
		final Perimetre perimetre = new Perimetre();
		perimetre.setDateCreation(perimetreDTO.getDateCreation());
		perimetre.setEtat(etatDAO.read(perimetreDTO.getEtatDTO().getId()));
		perimetre.setLibelle(perimetreDTO.getLibelle());
		perimetreDAO.persist(perimetre);

		// Je recupére le créateur de ce périmetre
		final Utilisateur userRecup = utilisateurDAO.read(idUserCreateur);
		// Je le notifie aux administrateurs de l'application
		notificationService.envoyerNotificationToUtilisateurByProfil(
				PropertiesUtils.getProperty(MESSAGE_NOTIF_PERIMETRE_CREE,
						UtilisateurMapper.getConcatenationPrenomNom(userRecup), perimetre.getLibelle()),
				ID_PROFIL_ADMINISTRATEUR);

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * fr.gfi.agraf.service.IPerimetreService#supprimerPerimetre(java.lang.Long)
	 */
	public void supprimerPerimetre(final Long idPerimetre, final Long idUserSuppr) throws AgrafException {

		// Je vérifie que le périmetre n'a pas d'activités liés
		final Perimetre perimetre = perimetreDAO.read(idPerimetre);
		final String libellePerimetre = perimetre.getLibelle();
		if (!CollectionUtils.isEmpty(perimetre.getActiviteSet())) {
			throw new AgrafException(ERREUR_PERIMETRE_NON_VIDE);
		}
		perimetreDAO.delete(idPerimetre);

		// Je recupére le créateur de ce périmetre
		final Utilisateur userRecup = utilisateurDAO.read(idUserSuppr);
		// Je le notifie aux administrateurs de l'application
		notificationService.envoyerNotificationToUtilisateurByProfil(
				PropertiesUtils.getProperty(MESSAGE_NOTIF_PERIMETRE_SUPPR,
						UtilisateurMapper.getConcatenationPrenomNom(userRecup), libellePerimetre),
				ID_PROFIL_ADMINISTRATEUR);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * fr.gfi.agraf.service.IPerimetreService#getListePerimetreByUtilisateurID
	 * (java.lang.Long)
	 */
	public List<PerimetreDTO> getListePerimetreByUtilisateurID(final Long idUtilisateur)
			throws AgrafException {
		final List<PerimetreDTO> perimetreList = PerimetreMapper.entityToDTOList(perimetreDAO
				.getListePerimetreByUtilisateurID(idUtilisateur));
		if (CollectionUtils.isEmpty(perimetreList)) {
			throw new AgrafException(UTILISATEUR_TACHE_AUCUNE);
		}

		return perimetreList;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * fr.gfi.agraf.service.IPerimetreService#exporterPerimetre(java.lang.Long)
	 */
	public HSSFWorkbook exporterPerimetre(final Long idPerimetre) throws AgrafException {
		// Récupere le perimetre
		final Perimetre perimetre = perimetreDAO.read(idPerimetre);
		// Verifie que le perimetre n'est pas null
		if (perimetre == null) {
			throw new AgrafException(ERREUR_PERIMETRE_NOTFOUND);
		}
		return poiPerimetreDAO.writePerimetre(PerimetreMapper.entityToDto(perimetre));
	}
}
